using System;
using System.Collections.Generic;
using System.Linq;

namespace OpenWaves.ActivityFeed.Web.Handler
{
    internal class ActionSelector : IActionSelector
    {
        public readonly string Method;
        public readonly UrlPath Path;

        public ActionSelector(string method, UrlPath path)
        {
            this.Method = method;
            this.Path = path;
        }

        public bool Match(string method, Url url, out IDictionary<string, string> parameters)
        {
            if (this.Method.Equals(method, StringComparison.OrdinalIgnoreCase) == false)
            {
                parameters = null;
                return false;
            }

            if (this.Path.IsAbsolute != url.Path.IsAbsolute)
            {
                parameters = null;
                return false;
            }

            if (this.Path.Segments.Count() != url.Path.Segments.Count())
            {
                parameters = null;
                return false;
            }

            var p = new Dictionary<string, string>();

            for (var i = 0; i < this.Path.Segments.Count(); i++)
            {
                if (MatchSegments(this.Path.Segments.ElementAt(i), url.Path.Segments.ElementAt(i), p) == false)
                {
                    parameters = null;
                    return false;
                }
            }

            // queryString parameters
            foreach(var q in url.Query)
            {
                p[q.Key] = q.Value;
            }

            parameters = p;
            return true;
        }

        private static bool MatchSegments(string expected, string acctual, IDictionary<string, string> parameters)
        {
            if (acctual.Equals(expected, StringComparison.OrdinalIgnoreCase))
                return true;

            if (expected.StartsWith("{", StringComparison.Ordinal) && expected.EndsWith("}", StringComparison.Ordinal))
            {
                var parameterName = expected.Substring(1, expected.Length - 2);
                parameters.Add(parameterName, acctual);
                return true;
            }

            return false;
        }
    }
}